package main

import (
	"SystemExploration/config"
	"SystemExploration/mongodb"
	"SystemExploration/mongodb/db"
	"SystemExploration/route"
	"SystemExploration/task"
	"context"
	"flag"
	"fmt"
	"github.com/gin-gonic/gin"
	confs "github.com/tal-tech/go-zero/core/conf"
	"log"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"
)

var configFile = flag.String("f", "etc/conf.yaml", "the config file")

func main() {

	//初始化配置文件
	flag.Parse()
	var c config.Config
	confs.MustLoad(*configFile, &c)

	if c.Mode == gin.ReleaseMode {
		gin.SetMode(gin.ReleaseMode)
	}

	//
	////初始化任务
	task.Init()

	//初始化 mongodb
	err := db.Init(c.MongoDB)
	if err != nil {
		log.Println("MongoDB", err)
	}
	defer db.Clone()

	//创建用户
	mongodb.AddUser()
	//初始化任务数据
	mongodb.TaskAdd()

	//服务启动
	r := route.Init()

	r.StaticFS("/web/", http.Dir("./Xadmin"))

	//6. 启动服务(优雅关机)
	srv := &http.Server{
		Addr:    fmt.Sprintf("%v:%d", c.Host, c.Port),
		Handler: r,
	}

	go func() {
		// 开启一个goroutine启动服务
		if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			log.Println("listen", err)
		}
	}()

	// 等待中断信号来优雅地关闭服务器，为关闭服务器操作设置一个5秒的超时
	quit := make(chan os.Signal, 1) // 创建一个接收信号的通道
	// kill 默认会发送 syscall.SIGTERM 信号
	// kill -2 发送 syscall.SIGINT 信号，我们常用的Ctrl+C就是触发系统SIGINT信号
	// kill -9 发送 syscall.SIGKILL 信号，但是不能被捕获，所以不需要添加它
	// signal.Notify把收到的 syscall.SIGINT或syscall.SIGTERM 信号转发给quit
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) // 此处不会阻塞
	<-quit                                               // 阻塞在此，当接收到上述两种信号时才会往下执行
	log.Println("Shutdown Server ...")
	// 创建一个5秒超时的context
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()
	// 5秒内优雅关闭服务（将未处理完的请求处理完再关闭服务），超过5秒就超时退出
	if err := srv.Shutdown(ctx); err != nil {
		log.Println("Server Shutdown: ", err)
	}

	log.Println("Server exiting")
}
